#pragma once
#include "GUIState.h"
#include "ReceivedDataRecord.h"
#include "SentDataRecord.h"

// Transfer Data Chart
//
// Used to plot the sent and received data.
//
// Uses fast plot to ensure that the data can be plotted in an acceptable time frame.
//
// Plots:
// * CSV Data (the recorded data from the helicopter)
// * The sent shaker A value
// * The sent shaker B value
// * The received shaker A value
// * The received shaker B value
// * The received accelerometer A value
// * The received accelerometer B value
// * The received accelerometer C value

namespace CC3501_Main_GUI {

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::Diagnostics;

	/// <summary>
	/// Summary for TransferDataChart
	/// </summary>
	public ref class TransferDataChart : public System::Windows::Forms::Form
	{
	public:
		TransferDataChart(GUIState^ existingState)
		{
			InitializeComponent();
			
			this->state = existingState;
			this->updateChart();			
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~TransferDataChart()
		{
			if (components)
			{
				delete components;
			}
		}
	private: System::Windows::Forms::DataVisualization::Charting::Chart^  chart1;
	protected: 

	private:		
		// Our save state
		GUIState^ state;
	private: System::Windows::Forms::Button^  button1;
	private: System::Windows::Forms::Panel^  panel1;
	private: System::Windows::Forms::CheckBox^  sentShakerBChekbox;
	private: System::Windows::Forms::CheckBox^  receivedShakerAChekbox;
	private: System::Windows::Forms::CheckBox^  receivedShakerBChekbox;
	private: System::Windows::Forms::CheckBox^  receivedAccelerometerAChekbox;
	private: System::Windows::Forms::CheckBox^  sentShakerAChekbox;
	private: System::Windows::Forms::CheckBox^  receivedAccelerometerCChekbox;
	private: System::Windows::Forms::CheckBox^  receivedAccelerometerBChekbox;
	private: System::Windows::Forms::CheckBox^  sentCSVDataCheckbox;

			 /// <summary>
			 /// Required designer variable.
			 /// </summary>
			 System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
			 /// <summary>
			 /// Required method for Designer support - do not modify
			 /// the contents of this method with the code editor.
			 /// </summary>
			 void InitializeComponent(void)
			 {
				 System::Windows::Forms::DataVisualization::Charting::ChartArea^  chartArea2 = (gcnew System::Windows::Forms::DataVisualization::Charting::ChartArea());
				 System::Windows::Forms::DataVisualization::Charting::Legend^  legend2 = (gcnew System::Windows::Forms::DataVisualization::Charting::Legend());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series9 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series10 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series11 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series12 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series13 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series14 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series15 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 System::Windows::Forms::DataVisualization::Charting::Series^  series16 = (gcnew System::Windows::Forms::DataVisualization::Charting::Series());
				 this->chart1 = (gcnew System::Windows::Forms::DataVisualization::Charting::Chart());
				 this->button1 = (gcnew System::Windows::Forms::Button());
				 this->panel1 = (gcnew System::Windows::Forms::Panel());
				 this->receivedAccelerometerCChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->receivedAccelerometerBChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->sentShakerBChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->receivedShakerAChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->receivedShakerBChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->receivedAccelerometerAChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->sentShakerAChekbox = (gcnew System::Windows::Forms::CheckBox());
				 this->sentCSVDataCheckbox = (gcnew System::Windows::Forms::CheckBox());
				 (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->chart1))->BeginInit();
				 this->panel1->SuspendLayout();
				 this->SuspendLayout();
				 // 
				 // chart1
				 // 
				 chartArea2->Area3DStyle->Enable3D = true;
				 chartArea2->Area3DStyle->PointDepth = 10;
				 chartArea2->Name = L"ChartArea1";
				 this->chart1->ChartAreas->Add(chartArea2);
				 legend2->Name = L"Legend1";
				 this->chart1->Legends->Add(legend2);
				 this->chart1->Location = System::Drawing::Point(12, 12);
				 this->chart1->Name = L"chart1";
				 series9->ChartArea = L"ChartArea1";
				 series9->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series9->Legend = L"Legend1";
				 series9->Name = L"Sent CSV Data";
				 series10->ChartArea = L"ChartArea1";
				 series10->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series10->Color = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(0)), static_cast<System::Int32>(static_cast<System::Byte>(192)), 
					 static_cast<System::Int32>(static_cast<System::Byte>(0)));
				 series10->Legend = L"Legend1";
				 series10->Name = L"Sent Shaker A";
				 series11->ChartArea = L"ChartArea1";
				 series11->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series11->Legend = L"Legend1";
				 series11->Name = L"Sent Shaker B";
				 series12->ChartArea = L"ChartArea1";
				 series12->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series12->Color = System::Drawing::Color::Gold;
				 series12->Legend = L"Legend1";
				 series12->Name = L"Received Shaker A";
				 series13->ChartArea = L"ChartArea1";
				 series13->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series13->Legend = L"Legend1";
				 series13->Name = L"Received Shaker B";
				 series14->ChartArea = L"ChartArea1";
				 series14->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series14->Legend = L"Legend1";
				 series14->Name = L"Received Accelerometer A";
				 series15->ChartArea = L"ChartArea1";
				 series15->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series15->Legend = L"Legend1";
				 series15->Name = L"Received Accelerometer B";
				 series16->ChartArea = L"ChartArea1";
				 series16->ChartType = System::Windows::Forms::DataVisualization::Charting::SeriesChartType::FastLine;
				 series16->Legend = L"Legend1";
				 series16->Name = L"Received Accelerometer C";
				 this->chart1->Series->Add(series9);
				 this->chart1->Series->Add(series10);
				 this->chart1->Series->Add(series11);
				 this->chart1->Series->Add(series12);
				 this->chart1->Series->Add(series13);
				 this->chart1->Series->Add(series14);
				 this->chart1->Series->Add(series15);
				 this->chart1->Series->Add(series16);
				 this->chart1->Size = System::Drawing::Size(839, 503);
				 this->chart1->TabIndex = 0;
				 this->chart1->Text = L"chart1";
				 // 
				 // button1
				 // 
				 this->button1->Location = System::Drawing::Point(3, 199);
				 this->button1->Name = L"button1";
				 this->button1->Size = System::Drawing::Size(183, 23);
				 this->button1->TabIndex = 1;
				 this->button1->Text = L"Update Chart";
				 this->button1->UseVisualStyleBackColor = true;
				 this->button1->Click += gcnew System::EventHandler(this, &TransferDataChart::updateButton_Click);
				 // 
				 // panel1
				 // 
				 this->panel1->Controls->Add(this->sentCSVDataCheckbox);
				 this->panel1->Controls->Add(this->receivedAccelerometerCChekbox);
				 this->panel1->Controls->Add(this->receivedAccelerometerBChekbox);
				 this->panel1->Controls->Add(this->sentShakerBChekbox);
				 this->panel1->Controls->Add(this->receivedShakerAChekbox);
				 this->panel1->Controls->Add(this->receivedShakerBChekbox);
				 this->panel1->Controls->Add(this->receivedAccelerometerAChekbox);
				 this->panel1->Controls->Add(this->sentShakerAChekbox);
				 this->panel1->Controls->Add(this->button1);
				 this->panel1->Location = System::Drawing::Point(857, 12);
				 this->panel1->Name = L"panel1";
				 this->panel1->Size = System::Drawing::Size(190, 225);
				 this->panel1->TabIndex = 2;
				 // 
				 // receivedAccelerometerCChekbox
				 // 
				 this->receivedAccelerometerCChekbox->AutoSize = true;
				 this->receivedAccelerometerCChekbox->Checked = true;
				 this->receivedAccelerometerCChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->receivedAccelerometerCChekbox->Location = System::Drawing::Point(4, 161);
				 this->receivedAccelerometerCChekbox->Name = L"receivedAccelerometerCChekbox";
				 this->receivedAccelerometerCChekbox->Size = System::Drawing::Size(183, 17);
				 this->receivedAccelerometerCChekbox->TabIndex = 8;
				 this->receivedAccelerometerCChekbox->Text = L"Show Received Accelerometer C";
				 this->receivedAccelerometerCChekbox->UseVisualStyleBackColor = true;
				 this->receivedAccelerometerCChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::receivedAccelerometerCChekbox_CheckedChanged);
				 // 
				 // receivedAccelerometerBChekbox
				 // 
				 this->receivedAccelerometerBChekbox->AutoSize = true;
				 this->receivedAccelerometerBChekbox->Checked = true;
				 this->receivedAccelerometerBChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->receivedAccelerometerBChekbox->Location = System::Drawing::Point(3, 138);
				 this->receivedAccelerometerBChekbox->Name = L"receivedAccelerometerBChekbox";
				 this->receivedAccelerometerBChekbox->Size = System::Drawing::Size(183, 17);
				 this->receivedAccelerometerBChekbox->TabIndex = 7;
				 this->receivedAccelerometerBChekbox->Text = L"Show Received Accelerometer B";
				 this->receivedAccelerometerBChekbox->UseVisualStyleBackColor = true;
				 this->receivedAccelerometerBChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::receivedAccelerometerBChekbox_CheckedChanged);
				 // 
				 // sentShakerBChekbox
				 // 
				 this->sentShakerBChekbox->AutoSize = true;
				 this->sentShakerBChekbox->Checked = true;
				 this->sentShakerBChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->sentShakerBChekbox->Location = System::Drawing::Point(3, 46);
				 this->sentShakerBChekbox->Name = L"sentShakerBChekbox";
				 this->sentShakerBChekbox->Size = System::Drawing::Size(125, 17);
				 this->sentShakerBChekbox->TabIndex = 6;
				 this->sentShakerBChekbox->Text = L"Show Sent Shaker B";
				 this->sentShakerBChekbox->UseVisualStyleBackColor = true;
				 this->sentShakerBChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::sentShakerBChekbox_CheckedChanged);
				 // 
				 // receivedShakerAChekbox
				 // 
				 this->receivedShakerAChekbox->AutoSize = true;
				 this->receivedShakerAChekbox->Checked = true;
				 this->receivedShakerAChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->receivedShakerAChekbox->Location = System::Drawing::Point(3, 69);
				 this->receivedShakerAChekbox->Name = L"receivedShakerAChekbox";
				 this->receivedShakerAChekbox->Size = System::Drawing::Size(149, 17);
				 this->receivedShakerAChekbox->TabIndex = 5;
				 this->receivedShakerAChekbox->Text = L"Show Received Shaker A";
				 this->receivedShakerAChekbox->UseVisualStyleBackColor = true;
				 this->receivedShakerAChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::receivedShakerAChekbox_CheckedChanged);
				 // 
				 // receivedShakerBChekbox
				 // 
				 this->receivedShakerBChekbox->AutoSize = true;
				 this->receivedShakerBChekbox->Checked = true;
				 this->receivedShakerBChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->receivedShakerBChekbox->Location = System::Drawing::Point(3, 92);
				 this->receivedShakerBChekbox->Name = L"receivedShakerBChekbox";
				 this->receivedShakerBChekbox->Size = System::Drawing::Size(149, 17);
				 this->receivedShakerBChekbox->TabIndex = 4;
				 this->receivedShakerBChekbox->Text = L"Show Received Shaker B";
				 this->receivedShakerBChekbox->UseVisualStyleBackColor = true;
				 this->receivedShakerBChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::receivedShakerBChekbox_CheckedChanged);
				 // 
				 // receivedAccelerometerAChekbox
				 // 
				 this->receivedAccelerometerAChekbox->AutoSize = true;
				 this->receivedAccelerometerAChekbox->Checked = true;
				 this->receivedAccelerometerAChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->receivedAccelerometerAChekbox->Location = System::Drawing::Point(3, 115);
				 this->receivedAccelerometerAChekbox->Name = L"receivedAccelerometerAChekbox";
				 this->receivedAccelerometerAChekbox->Size = System::Drawing::Size(183, 17);
				 this->receivedAccelerometerAChekbox->TabIndex = 3;
				 this->receivedAccelerometerAChekbox->Text = L"Show Received Accelerometer A";
				 this->receivedAccelerometerAChekbox->UseVisualStyleBackColor = true;
				 this->receivedAccelerometerAChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::receivedAccelerometerAChekbox_CheckedChanged);
				 // 
				 // sentShakerAChekbox
				 // 
				 this->sentShakerAChekbox->AutoSize = true;
				 this->sentShakerAChekbox->Checked = true;
				 this->sentShakerAChekbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->sentShakerAChekbox->Location = System::Drawing::Point(3, 23);
				 this->sentShakerAChekbox->Name = L"sentShakerAChekbox";
				 this->sentShakerAChekbox->Size = System::Drawing::Size(125, 17);
				 this->sentShakerAChekbox->TabIndex = 2;
				 this->sentShakerAChekbox->Text = L"Show Sent Shaker A";
				 this->sentShakerAChekbox->UseVisualStyleBackColor = true;
				 this->sentShakerAChekbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::sentShakerAChekbox_CheckedChanged);
				 // 
				 // sentCSVDataCheckbox
				 // 
				 this->sentCSVDataCheckbox->AutoSize = true;
				 this->sentCSVDataCheckbox->Checked = true;
				 this->sentCSVDataCheckbox->CheckState = System::Windows::Forms::CheckState::Checked;
				 this->sentCSVDataCheckbox->Location = System::Drawing::Point(3, 3);
				 this->sentCSVDataCheckbox->Name = L"sentCSVDataCheckbox";
				 this->sentCSVDataCheckbox->Size = System::Drawing::Size(128, 17);
				 this->sentCSVDataCheckbox->TabIndex = 9;
				 this->sentCSVDataCheckbox->Text = L"Show Sent CSV Data";
				 this->sentCSVDataCheckbox->UseVisualStyleBackColor = true;
				 this->sentCSVDataCheckbox->CheckedChanged += gcnew System::EventHandler(this, &TransferDataChart::sentCSVDataCheckbox_CheckedChanged);
				 // 
				 // TransferDataChart
				 // 
				 this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
				 this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
				 this->ClientSize = System::Drawing::Size(1056, 526);
				 this->Controls->Add(this->panel1);
				 this->Controls->Add(this->chart1);
				 this->Name = L"Data Transfer Graph";
				 this->Text = L"Data Transfer Graph";
				 (cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->chart1))->EndInit();
				 this->panel1->ResumeLayout(false);
				 this->panel1->PerformLayout();
				 this->ResumeLayout(false);

			 }
#pragma endregion

	// Function to update the chart
	private: System::Void updateChart(void) {
				 
				 // Clear tha chart data
				 chart1->Series["Sent CSV Data"]->Points->Clear();

				 chart1->Series["Sent Shaker A"]->Points->Clear();
				 chart1->Series["Sent Shaker B"]->Points->Clear();

				 chart1->Series["Received Shaker A"]->Points->Clear();
				 chart1->Series["Received Shaker B"]->Points->Clear();

				 chart1->Series["Received Accelerometer A"]->Points->Clear();
				 chart1->Series["Received Accelerometer B"]->Points->Clear();
				 chart1->Series["Received Accelerometer C"]->Points->Clear();

				 List<SentDataRecord^>^ sentRecords = this->state->getSentDataRecords();
				 List<ReceivedDataRecord^>^ receivedRecords = this->state->getReceivedDataRecords();

				 int j = 0;

				 ReceivedDataRecord^ rd = nullptr;

				 for (int i = 0; i < sentRecords->Count; i++) {
					SentDataRecord^ sd = sentRecords[i];

					if ( rd == nullptr && j < receivedRecords->Count) {
						rd = receivedRecords[j];
					}

					chart1->Series["Sent CSV Data"]->Points->AddXY(i, sd->getCSVData());
					chart1->Series["Sent Shaker A"]->Points->AddXY(i, sd->getShakerAValue());
					chart1->Series["Sent Shaker B"]->Points->AddXY(i, sd->getShakerBValue());

					if ( ( rd != nullptr ) && ( sd->getIndex() == rd->getIndex() ) ) {			
						chart1->Series["Received Shaker A"]->Points->AddXY(i, rd->getShakerAValue());
						chart1->Series["Received Shaker B"]->Points->AddXY(i, rd->getShakerBValue());

						chart1->Series["Received Accelerometer A"]->Points->AddXY(i, rd->getAccelerometerAValue());
						chart1->Series["Received Accelerometer B"]->Points->AddXY(i, rd->getAccelerometerBValue());
						chart1->Series["Received Accelerometer C"]->Points->AddXY(i, rd->getAccelerometerCValue());
				 		
						j++;
						rd = nullptr;				
					}
				 }

				 // Tell the chart to update
				 chart1->Invalidate();
			 }

	private: System::Void updateButton_Click(System::Object^  sender, System::EventArgs^  e) {
				 try {
					 // Update the chart
					 this->updateChart();
				 } catch (System::InvalidOperationException^ err) {
					 // ignore the exception (it occurs because the background thread is adding to
					 // the list while we are trying to update the chart)
				 }
			 }

	// Checkboxes to enable/disable plots on the chart

	private: System::Void sentShakerAChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Sent Shaker A"]->Enabled = this->sentShakerAChekbox->Checked;
			 }
	
	private: System::Void sentShakerBChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Sent Shaker B"]->Enabled = this->sentShakerBChekbox->Checked;
			 }

	private: System::Void receivedShakerAChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Received Shaker A"]->Enabled = this->receivedShakerAChekbox->Checked;
			 }
	
	private: System::Void receivedShakerBChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Received Shaker B"]->Enabled = this->receivedShakerBChekbox->Checked;
			 }
	
	private: System::Void receivedAccelerometerAChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Received Accelerometer A"]->Enabled = this->receivedAccelerometerAChekbox->Checked;
			 }
	
	private: System::Void receivedAccelerometerBChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Received Accelerometer B"]->Enabled = this->receivedAccelerometerBChekbox->Checked;
			 }
	
	private: System::Void receivedAccelerometerCChekbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Received Accelerometer C"]->Enabled = this->receivedAccelerometerCChekbox->Checked;
			 }

	private: System::Void sentCSVDataCheckbox_CheckedChanged(System::Object^  sender, System::EventArgs^  e) {
				 chart1->Series["Sent CSV Data"]->Enabled = this->sentCSVDataCheckbox->Checked;
			 }
	};

}
